{{!

  Copyright (c) Meta Platforms, Inc. and affiliates.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

}}{{!

This portion of types.pxd contains mainly thrift-py3-only declarations that are
incompatible with thrift-python and a few extern cpp bindings not used by
thrift-py3 cython users.

}}

{{> types/cimport_std }}
{{> types/cimport_thrift }}
cimport thrift.py3.exceptions
cimport thrift.py3.types
from libc.stdint cimport int64_t
from thrift.python.common cimport (
    RpcOptions as __RpcOptions,
    MetadataBox as __MetadataBox,
)
from folly.optional cimport cOptional as __cOptional
{{#program:has_stream?}}
from folly cimport cFollyTry
from cpython.ref cimport PyObject
from thrift.py3.stream cimport (
    ClientBufferedStream, cClientBufferedStream, cClientBufferedStreamWrapper,
    ResponseAndClientBufferedStream, cResponseAndClientBufferedStream,
    ServerStream, cServerStream, ResponseAndServerStream
)
{{/program:has_stream?}}

{{#program:includeNamespaces}}
{{#hasTypes?}}
cimport {{#includeNamespace}}{{value}}.{{/includeNamespace}}types as _{{#includeNamespace}}{{value}}_{{/includeNamespace}}types
cimport {{#includeNamespace}}{{value}}.{{/includeNamespace}}cbindings as _{{#includeNamespace}}{{value}}_{{/includeNamespace}}cbindings
{{/hasTypes?}}
{{/program:includeNamespaces}}

cimport {{#program:py3Namespaces}}{{value}}.{{/program:py3Namespaces}}{{program:name}}.types as _fbthrift_types
cimport {{#program:py3Namespaces}}{{value}}.{{/program:py3Namespaces}}{{program:name}}.types_fields as _fbthrift_types_fields
cimport {{#program:py3Namespaces}}{{value}}.{{/program:py3Namespaces}}{{program:name}}.cbindings as {{> types/current_module_cbindings}}

cdef extern from "{{program:include_prefix}}gen-py3/{{program:name}}/types.h":
  pass
{{#program:python_capi_converter?}}
cdef extern from "{{program:include_prefix}}gen-python-capi/{{program:name}}/thrift_types_capi.h":
    cppclass _fbthrift__NamespaceTag "{{program:capi_module_prefix}}::NamespaceTag"

{{/program:python_capi_converter?}}

{{^program:inplace_migrate?}}
{{#program:filtered_structs}}


cdef class {{struct:name}}({{> types/python_struct_class}}):
    cdef shared_ptr[{{> types/current_module_cbindings}}.{{> types/c_struct }}] _cpp_obj_FBTHRIFT_ONLY_DO_NOT_USE
    {{^struct:union?}}
    cdef _fbthrift_types_fields.__{{struct:name}}_FieldsSetter _fields_setter
    {{#struct:py3_fields}}
    cdef inline object {{field:py_name}}_impl(self)
    {{/struct:py3_fields}}
    {{!Memoized Python wrappers of struct fields, created lazily}}
    {{#struct:py3_fields}}
    {{#field:type}}{{#type:structured}}
    cdef {{> types/cython_python_type}} __fbthrift_cached_{{field:py_name}}
    {{/type:structured}}{{#type:container?}}
    cdef {{> types/cython_python_type}} __fbthrift_cached_{{field:py_name}}
    {{/type:container?}}{{#type:enum?}}
    cdef object __fbthrift_cached_{{field:py_name}}
    {{/type:enum?}}{{#type:iobuf?}}
    cdef _fbthrift_iobuf.IOBuf __fbthrift_cached_{{field:py_name}}
    {{/type:iobuf?}}{{#type:iobufRef?}}
    cdef _fbthrift_iobuf.IOBuf __fbthrift_cached_{{field:py_name}}
    {{/type:iobufRef?}}{{/field:type}}
    {{/struct:py3_fields}}{{/struct:union?}}
    {{#struct:union?}}
    cdef int64_t type_int
    cdef object py_type
    cdef object py_value
    cdef _initialize_py({{struct:name}} self)
    {{/struct:union?}}
    {{#struct:union?}}

    @staticmethod
    cdef unique_ptr[{{> types/current_module_cbindings}}.{{> types/c_struct }}] _make_instance(
        {{> types/current_module_cbindings}}.{{> types/c_struct }}* base_instance{{^struct:union?}},
        bint* __isNOTSET{{/struct:union?}}{{#struct:py3_fields}},
        {{#field:type}}{{!
            }}{{#type:cythonTypeNoneable?}}{{!
                }}{{> types/cython_python_type}} {{!
            }}{{/type:cythonTypeNoneable?}}{{!
            }}{{^type:cythonTypeNoneable?}}{{!
                }}object {{!
            }}{{/type:cythonTypeNoneable?}}{{!
            }}{{field:py_name}}{{!
        }}{{/field:type}}{{/struct:py3_fields}}
    ) except *
    {{/struct:union?}}

    @staticmethod
    cdef _create_FBTHRIFT_ONLY_DO_NOT_USE(shared_ptr[{{> types/current_module_cbindings}}.{{> types/c_struct }}])

{{/program:filtered_structs}}

{{#program:containerTypes}}
cdef {{> types/cython_cpp_type}}{{!
}} {{type:flat_name}}__make_instance(object items) except *
{{^program:auto_migrate?}}
cdef object {{type:flat_name}}__from_cpp(const {{> types/cython_cpp_type}}&) except *
{{/program:auto_migrate?}}

{{/program:containerTypes}}
{{/program:inplace_migrate?}}

{{#program:has_stream?}}{{! check if it's a stream case and if not short-circuit it to save get stream_types calls }}

{{#program:stream_types}}
cdef class ClientBufferedStream__{{type:flat_name}}(ClientBufferedStream):
    cdef unique_ptr[cClientBufferedStreamWrapper[{{> types/cython_cpp_type}}]] _gen

    @staticmethod
    cdef _fbthrift_create(cClientBufferedStream[{{> types/cython_cpp_type}}]& c_obj, __RpcOptions rpc_options)

    @staticmethod
    cdef void callback(
        cFollyTry[__cOptional[{{> types/cython_cpp_type}}]]&& res,
        PyObject* userdata,
    ) noexcept

cdef class ServerStream__{{type:flat_name}}(ServerStream):
    pass

{{/program:stream_types}}
{{#program:response_and_stream_functions}}{{#function:return_type}}

cdef class ResponseAndClientBufferedStream__{{> stream/response_class_name_suffix}}(ResponseAndClientBufferedStream):
    cdef ClientBufferedStream__{{#function:stream_elem_type}}{{type:flat_name}}{{/function:stream_elem_type}} _stream
    cdef {{#function:stream_first_response_type}}{{> types/cython_python_type}}{{/function:stream_first_response_type}} _response

    @staticmethod
    cdef _fbthrift_create(cResponseAndClientBufferedStream[{{!
        }}{{#function:stream_first_response_type}}{{> types/cython_cpp_type}}{{/function:stream_first_response_type}}, {{!
        }}{{#function:stream_elem_type}}{{> types/cython_cpp_type}}{{/function:stream_elem_type}}]& c_obj, __RpcOptions rpc_options)


cdef class ResponseAndServerStream__{{> stream/response_class_name_suffix}}(ResponseAndServerStream):
    pass

{{/function:return_type}}{{/program:response_and_stream_functions}}
{{/program:has_stream?}}
{{#program:inplace_migrate?}}{{#program:needs_container_converters?}}
{{#program:containerTypes}}
cdef {{> types/cython_cpp_type}} {{type:flat_name}}__make_instance(object items) except *
cdef object {{type:flat_name}}__from_cpp(const {{> types/cython_cpp_type}}&) except *

{{/program:containerTypes}}
{{/program:needs_container_converters?}}{{/program:inplace_migrate?}}
